// 
// SoapTrace.Net - A soap message monitoring utility. 
// 
// Copyright (C) 2004 Matthew Ward
// 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
// 
// Matthew Ward (mrward@users.sourceforge.net)
// 


using SoapTrace.Core.Diagnostics;
using System;
using System.Diagnostics;
using System.Net.Sockets;

namespace SoapTrace.Core.Communication
{
	/// <summary>
	/// Represents a channel between a client and the remote server.
	/// </summary>
	public sealed class ProxyChannel
	{
		/// <summary>
		/// The client connection
		/// </summary>
		private TcpSocketConnection m_ClientConnection;
		
		/// <summary>
		/// The server connection.
		/// </summary>
		private TcpSocketConnection m_ServerConnection;
		
		/// <summary>
		/// Bytes read from the client.
		/// </summary>
		private ByteArray m_ReadClientBytes = new ByteArray( );
		
		/// <summary>
		/// Bytes read from the server.
		/// </summary>
		private ByteArray m_ReadServerBytes = new ByteArray( );
		
		/// <summary>
		/// Status flag that indicates that this channel is open.
		/// </summary>
		private bool m_IsOpen;
		
		/// <summary>
		/// Creates a new instance of this class.
		/// </summary>
		public ProxyChannel( TcpSocketConnection clientConnection, 
		                     TcpSocketConnection serverConnection )
		{
			Debug.Assert( clientConnection != null, "Null client socket passed." );
			Debug.Assert( serverConnection != null, "Null server connection passed." );
			
			m_ClientConnection = clientConnection;
			
			m_ServerConnection = serverConnection;
			
			m_IsOpen = true;
		}
		
		/// <summary>
		/// Closes this channel.
		/// </summary>
		public void Close( )
		{
			Logger.LogDebug( "ProxyChannel::Close in." );
		
			m_ClientConnection.Close( );
			m_ClientConnection = null;
			
			m_ServerConnection.Close( );
			m_ServerConnection = null;
			
			Logger.LogDebug( "ProxyChannel::Close out." );
		}
		
		/// <summary>
		/// Gets whether this channel is open.
		/// </summary>
		public bool IsOpen
		{
			get
			{
				return m_IsOpen;
			}
		}

		/// <summary>
		/// Processes the proxy channel.  
		/// </summary>
		/// <remarks>This method is responsible for reading client
		/// requests and forwarding them onto the server, reading the server
		/// responses and forwarding them to the client.</remarks>
		public void Process( )
		{
			// Read any requests sent from the client.
			
			m_IsOpen = m_ClientConnection.Read( m_ServerConnection );

			if( m_IsOpen )
			{
				// Reads any data responses from the server.
				
				m_IsOpen = m_ServerConnection.Read( m_ClientConnection );
			}

			if( m_IsOpen )
			{
				// Sends any data from the server to the client.

				m_ClientConnection.Send( );

				// Sends any data from the client to the server.

				m_ServerConnection.Send( );
			}
		}
	}
}
